package org.lemma.number;

import java.io.Serializable;
import javax.annotation.Author;
import javax.annotation.Copyright;
import javax.annotation.Version;

/**
 * <p>
 *  TODO: Javadoc for {@code Digit}
 * </p>
 *
 * @author Chris Beatty [christopher.beatty@gmail.com]
 * @version 1.0.0
 */
@Version (
    major="1", minor="0", patch="0", 
    date="Jun 16, 2008 4:14:36 PM",
    authors = {
        @Author (name="Chris Beatty", email="christopher.beatty@gmail.com")
    }
) @Copyright 
public class Digit extends Natural implements Cloneable, Serializable {

    /**
     * Determines if a de-serialized file is compatible with this class.
     *
     * Maintainers must change this value if and only if the new version
     * of this class is not compatible with old versions. See Sun docs
     * for <a href="http://java.sun.com/products/jdk/1.1/docs/guide
     * /serialization/spec/version.doc.html">details.</a>
     */
    private static final long serialVersionUID = 1L;

    /**
     * Enumeration of commonly used bases
     */
    public enum Base {
        Binary, Decimal, Octal, Hexadecimal;
    }

    /**
     * The symbolic representation of this {@code Digit}
     */
    private Character symbol = '0';

    /**
     * Default Class Constructor
     * Creates and initializes a new instance of {@code Digit}
     */
    protected Digit() {
        super();
    }

    /**
     * Class Constructor
     * Creates a new instance of {@code Digit} and initializes is
     * symbolic representation
     *
     * @param d A {@code Character}
     */
    public Digit(Character d) {
        this();
        if(d != null) {
            this.symbol = d;
        } else {
            throw new IllegalArgumentException("NULL value");
        }
    }

    /**
     * Class Constructor
     * Creates a new instance of {@code Digit} and initializes is
     * symbolic representation
     *
     * @param d A {@code char}
     */
    public Digit(char d) {
        this(new Character(d));
    }

    /**
     * Tests the equality of two {@code Digit} objects
     *
     * @param d A {@code Digit}
     * @return Returns {@code true} if the given {@code Digit} is
     *         equal to {@code this}; otherwise, {@code false} is
     *         returned
     */
    public boolean equals(Digit d) {
        if(d != null) {
            if(this.symbol == null && d.symbol == null) {
                return true;
            } else if(this.symbol == null || d.symbol == null) {
                return false;
            } else {
                return this.symbol.equals(d.symbol);
            }
        } else {
            return false;
        }
    }

    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Digit) {
            return this.equals((Digit) obj);
        } else {
            return false;
        }
    }

    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return (symbol != null) ? symbol.hashCode() : 0;
    }

    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     * @throws java.lang.CloneNotSupportedException
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        return new Digit(new Character(this.symbol.charValue()));
    }

    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     */
    @Override
    public String toString() {
        return this.symbol.toString();
    }
}
